#pragma once
#include <iostream>
#include <string>
#include <cassert>
#include <jsoncpp/json/json.h>
#include "log.hpp"

#define CRLF "\r\n"
#define CRLF_LEN strlen(CRLF)
#define SPACE ' '
#define SPACE_LEN 1
#define OPS "+-*/%"

using std::string;

// #define MY_SELF
void clearSpace(string &message)
{
    string ret;
    for (auto c : message)
    {
        if (c != SPACE)
            ret.push_back(c);
    }
    message.swap(ret);
}

// 9\r\n210 + 100\r\n
void decode(string &in, uint32_t *len)
{
    // 1.查找\r\n,判断是否是有效字符串
    *len = 0;
    int pos = in.find(CRLF);
    if (pos == string::npos)
        return;
    // 2.提取长度
    int inlen = atoi(in.substr(0, pos).c_str());
    // 3.确认有效载荷是否符合要求
    int leftLen = in.size() - 2 * CRLF_LEN - pos;
    if (leftLen < inlen)
        return;
    // 4.获取完整报文
    in = in.substr(pos + CRLF_LEN, leftLen);
    *len = leftLen;
}

// 1 + 1->strlen\r\n1 + 1\r\n
void encode(string *package)
{
    int strlen = package->size();
    string encodeStr = to_string(strlen);
    encodeStr += CRLF;
    encodeStr += *package;
    encodeStr += CRLF;
    package->swap(encodeStr);
}
class Request
{
public:
    Request() {}
    ~Request() {}
    // 结构化数据->字符串：1 + 1
    void serialize(string *package)
    {
#ifdef MY_SELF
        *package = to_string(x_);
        *package += SPACE;
        *package += op_;
        *package += SPACE;
        *package += to_string(y_);
#else
        // jsoncpp
        Json::Value root;
        root["x"] = x_;
        root["y"] = y_;
        root["op"] = op_;
        Json::FastWriter fw;
        *package = fw.write(root);
#endif
    }

    // 1 + 1->结构化数据
    bool deserialize(string &package)
    {
#ifdef MY_SELF
        int lpos = package.find(SPACE);
        if (lpos == string::npos)
            return false;
        int rpos = package.rfind(SPACE);
        if (rpos == string::npos)
            return false;
        x_ = atoi(package.substr(0, lpos).c_str());
        y_ = atoi(package.substr(rpos + 1).c_str());
        op_ = package[lpos + 1];
        return true;
#else
        // jsoncpp
        Json::Value root;
        Json::Reader rd;
        rd.parse(package, root);
        x_ = root["x"].asInt();
        y_ = root["y"].asInt();
        op_ = root["op"].asInt();
        return true;
#endif
    }

public:
    int x_;
    int y_;
    char op_;
};

class Response
{
public:
    Response() {}
    ~Response() {}
    // 0 100->结构化数据
    bool deserialize(string &package)
    {
#ifdef MY_SELF
        int pos = package.find(SPACE);
        if (pos == string::npos)
            return false;
        exitCode_ = atoi(package.substr(0, pos).c_str());
        result_ = atoi(package.substr(pos + SPACE_LEN).c_str());
        return true;
#else
        Json::Value root;
        Json::Reader rd;
        rd.parse(package, root);
        exitCode_ = root["exitcode"].asInt();
        result_ = root["result"].asInt();
        return true;
#endif
    }
    // 结构化->0 100
    void serialize(string &package)
    {
#ifdef MY_SELF
        package = to_string(exitCode_);
        package += SPACE;
        package += to_string(result_);
#else
        Json::Value root;
        Json::FastWriter fw;
        root["exitcode"] = exitCode_;
        root["result"] = result_;
        package = fw.write(root);
#endif
    }
    int exitCode_;
    int result_;
};

// 1+1 200/99
bool makeRequest(string &message, Request *req)
{
    char strTemp[BUFFER_SIZE];
    // snprintf(strTemp, sizeof(strTemp), message.c_str());error,1%1->1%被格式化为1%
    snprintf(strTemp, sizeof(strTemp), "%s", message.c_str());
    // cout << strTemp << endl;
    char *left = strtok(strTemp, OPS);
    if (!left)
    {
        cout << left << endl;
        return false;
    }
    char *right = strtok(nullptr, OPS);
    if (!right)
    {
        cout << right << endl;
        return false;
    }
    char op = message[strlen(left)];
    req->x_ = atoi(left);
    req->y_ = atoi(right);
    req->op_ = op;
    return true;
}